package com.duoec.dw.lineage.service.analyser.query;

import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.duoec.dw.lineage.dto.TableFieldLineageDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import com.duoec.dw.lineage.exceptions.LineageAnalyseException;
import com.duoec.dw.lineage.service.LineageTableService;
import com.duoec.dw.lineage.core.utils.AnalyserUtils;
import com.duoec.dw.lineage.dto.MultiTableLineageDto;
import com.duoec.dw.lineage.service.HiveAnalyser;
import com.duoec.dw.lineage.service.analyser.HiveQueryAnalyser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.LinkedHashSet;
import java.util.List;

/**
 * @author xuwenzhen
 */
public abstract class BaseQueryAnalyser<T extends SQLSelectQuery> implements HiveQueryAnalyser<T> {
    @Autowired
    protected HiveAnalyser hiveAnalyser;

    @Autowired
    private LineageTableService lineageTableService;

    public void setHiveAnalyser(HiveAnalyser hiveAnalyser) {
        this.hiveAnalyser = hiveAnalyser;
    }

    protected void selectFieldsAnalyser(TableLineageDto tableLineage, MultiTableLineageDto fromTableLineages, List<SQLSelectItem> selectList) {
        //重置字段
        LinkedHashSet<TableFieldLineageDto> fields = new LinkedHashSet<>();
        tableLineage.setFields(fields);

        selectList.forEach(item -> getTableFieldLineage(tableLineage, fromTableLineages, item));

        //补全字段信息
        AnalyserUtils.fixFieldInfo(tableLineage);
    }

    private void getTableFieldLineage(TableLineageDto tableLineage, MultiTableLineageDto fromTableLineages, SQLSelectItem item) {
        LinkedHashSet<TableFieldLineageDto> fieldLineages = hiveAnalyser.analyseSelect(tableLineage, fromTableLineages, item.getExpr());
        if (CollectionUtils.isEmpty(fieldLineages)) {
            throw new LineageAnalyseException("字段解析错误！字段为空！");
        }

        //设置别名
        String alias = item.getAlias();
        if (!StringUtils.isEmpty(alias)) {
            TableFieldLineageDto firstFieldLineage = fieldLineages.iterator().next();
            firstFieldLineage.setAlias(firstFieldLineage.getColName());
            firstFieldLineage.setColName(AnalyserUtils.formatFieldName(alias));
        }

        tableLineage.getFields().addAll(fieldLineages);
    }

    public void setLineageTableService(LineageTableService lineageTableService) {
        this.lineageTableService = lineageTableService;
    }
}
